<template>
  <div class="home">
    <el-button @click="addPoints" class="btn">按钮</el-button>
    <div id="map" @click="selectPoint"></div>
  </div>
</template>

<script>
import * as THREE from "three"; //引入Threejs
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
let scene;
let geometry;
let materialBox;
let materialLine;
let points;
let mesh;
let point;
let ambient;
let width;
let height;
let camera;
let renderer;
let controls;
let x;
let y;
let origin;
let cameraPosition;
export default {
  data() {
    return {
      myDom: undefined,
      p1: new THREE.Vector3(-80, 0, 0),
      p2: new THREE.Vector3(-40, 100, 0),
      p3: new THREE.Vector3(40, 100, 0),
      p4: new THREE.Vector3(80, 0, 0),
      path: undefined,
      isAdd: false,
      bonce: undefined,
      bonceFlag: true,
      pointsList: [],
    };
  },
  mounted() {
    this.myDom = document.getElementById("map");
    console.log(this.myDom);
    this.initMap();
  },

  methods: {
    initMap() {
      /**
       * 创建场景对象Scene
       */
      scene = new THREE.Scene();

      geometry = new THREE.BufferGeometry(); //声明一个几何体对象Geometry
      this.path = new THREE.CubicBezierCurve3(
        this.p1,
        this.p2,
        this.p3,
        this.p4
      );

      //getPoints是基类Curve的方法，返回一个vector3对象作为元素组成的数组
      points = this.path.getPoints(100); //分段数100，返回101个顶点
      // setFromPoints方法从points中提取数据改变几何体的顶点属性vertices
      geometry.setFromPoints(points);
      materialLine = new THREE.LineBasicMaterial({
        color: 0x000000,
      });

      var line = new THREE.Line(geometry, materialLine); //网格模型对象Mesh
      console.log(line);
      scene.add(line); //网格模型添加到场景中

      /**
       * 光源设置
       */
      //点光源
      point = new THREE.PointLight(0xffffff);
      point.position.set(400, 200, 300); //点光源位置
      scene.add(point); //点光源添加到场景中
      //环境光
      ambient = new THREE.AmbientLight(0x444444);
      scene.add(ambient);
      // console.log(scene)
      // console.log(scene.children)
      /**
       * 相机设置
       */
      width = 1200; //窗口宽度
      height = 800; //窗口高度
      origin = { x: width / 2, y: height / 2 };
      let k = width / height; //窗口宽高比
      let s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
      //创建相机对象
      camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
      camera.position.set(0, 0, 1000); //设置相机位置
      cameraPosition= camera.position
      camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
      camera.updateProjectionMatrix();
      /**
       * 创建渲染器对象
       */
      renderer = new THREE.WebGLRenderer();
      renderer.setSize(width, height); //设置渲染区域尺寸
      renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
      this.myDom.appendChild(renderer.domElement); //body元素中插入canvas对象
      this.render();
      controls = new OrbitControls(camera, renderer.domElement); //创建控件对象
      console.log(controls, "controls");
      controls.enableRotate = false;
      controls.addEventListener('start', this.startDrag);
      controls.addEventListener('end', this.endDrag);
      //执行渲染操作   指定场景、相机作为参数
    },
    addPoints() {
      this.isAdd = !this.isAdd;
    },
    moveInMap(event) {
      if (this.bonceFlag) {
        this.bonceFlag = false;
        clearTimeout(this.bonce);
        this.bonce = setTimeout(() => {
          if (scene.getObjectByName("newLine")) {
            scene.remove(scene.getObjectByName("newLine"));
          }
          x =
            event.offsetX < width / 2
              ? event.offsetX - width / 2
              : event.offsetX - width / 2;
          y =
            event.offsetY < height / 2
              ? height / 2 - event.offsetY
              : height / 2 - event.offsetY;

          console.log(x, y);
          let geometry = new THREE.BufferGeometry();
          let vertices = new Float32Array([]);
          geometry.setAttribute(
            "position",
            new THREE.BufferAttribute(vertices, 3)
          );
          console.log(geometry);
          // geometry.setFromPoints(path.getPoints(100));
          let line = new THREE.Line(geometry, materialLine);
          line.name = "newLine";
          scene.add(line);
          this.bonceFlag = true;
        }, 100);
      }
    },
    // 地图选点
    selectPoint(event) {
      this.pointsList.push({
        x: event.offsetX,
        y: event.offsetY,
      });
      if (this.pointsList.length < 3) {
        if (this.pointsList.length == 1) {
          this.drawDot(this.pointsList[0].x, this.pointsList[0].y, 0.5,'first');
        }
        if (this.pointsList.length == 2) {
          this.drawLine(this.pointsList[1]);
          this.drawDot(this.pointsList[1].x, this.pointsList[1].y, 0.5,'scend');
        }
      } else {
        this.pointsList.splice(1, 2, {
          x: event.offsetX,
          y: event.offsetY,
        });
        this.drawLine(this.pointsList[1]);
        this.drawDot(this.pointsList[1].x, this.pointsList[1].y, 0.5,'scend');
      }
      console.log(this.pointsList, "this.pointsList");
    },
    // 画线
    drawLine({ x, y }, z = 0.5) {
      const name = "line";
      if (scene.getObjectByName(name)) {
        scene.remove(scene.getObjectByName(name));
      }
      let geometry = new THREE.BufferGeometry();
      let vertices = new Float32Array([
        ...this.convertCoodsToThree(this.pointsList[0].x,this.pointsList[0].y,0.5),
        ...this.convertCoodsToThree(x,y,z)
      ]);
      geometry.setAttribute("position", new THREE.BufferAttribute(vertices, 3));
      let material = new THREE.LineBasicMaterial({ vertexColors: true });
      let line = new THREE.Line(geometry, material);
      line.name = name;
      scene.add(line);
    },
    // 画点
    drawDot(x, y, z = 0,name) {
      if (scene.getObjectByName(name)) {
        scene.remove(scene.getObjectByName(name));
      }
      let geometry = new THREE.SphereGeometry(1, 64, 64);
      console.log(this.convertCoodsToThree(x, y,0.5),'111');
     console.log(geometry,'geometry');
      // geometry.position.set(this.convertCoodsToThree(x, y, z)) 

      let material = new THREE.PointsMaterial({
        color: 0xff0000,
        size: 5.0, //点对象像素尺寸
      }); //材质对象
      let points = new THREE.Points(geometry, material); //点模型对象
      points.position.set(...this.convertCoodsToThree(x, y, z)) 
      points.matrixAutoUpdate = false;
      points.updateMatrix()
      console.log(points);
      points.name = name;
      // points.position = new THREE.Vector3(x,y,z)

      scene.add(points);
    },
    render() {
      renderer.render(scene, camera); //执行渲染操作
      // mesh.rotateY(0.01);//每次绕y轴旋转0.01弧度
      requestAnimationFrame(this.render); //请求再次执行渲染函数render
    },

    // 屏幕坐标转标准设备坐标
    convertCoodsToThree(x, y, z = 0) {
      const x1 = (x / width) * 2 - 1;
      const y1 = -(y / height) * 2 + 1;
      //标准设备坐标(z=0.5这个值比较靠经验)
      const stdVector = new THREE.Vector3(x1, y1, 0);
      //世界坐标
      const worldVector = stdVector.unproject(camera);
      return worldVector;
    },
    // 拖拽事件开始
    startDrag(){
      console.log('startDrag');
      console.log(camera.position);
      cameraPosition = camera.position
      console.log('----------');
    },
    // 拖拽事件结束
    endDrag(){
      cameraPosition.x = camera.position.x- cameraPosition.x
      cameraPosition.y = camera.position.y- cameraPosition.y
      cameraPosition.z = camera.position.z- cameraPosition.z
      console.log('endDrag');
      console.log(camera.position);

    }
  },
};
</script>

<style lang="less" scoped>
.home {
  padding: 0;
  margin: 0;
  overflow: hidden;
  position: relative;
  .btn {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
  }
  #map {
    // position: absolute;
    // left: 50%;
    // top: 100px;
    // transform: translateX(-50%);
    // margin: 0 auto;
  }
}
</style>